package com.dingwen.treasure.core.service.impl;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.dingwen.treasure.base.enums.CaptchaEnum;
import com.dingwen.treasure.base.exception.CaptchaException;
import com.dingwen.treasure.base.pojo.vo.Result;
import com.dingwen.treasure.core.config.CaptchaProperties;
import com.dingwen.treasure.core.service.CaptchaService;
import com.dingwen.treasure.model.vo.CaptchaVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

/**
 * 　CaptchaServiceImpl
 * 　@author dingwen
 * 　@date 2022/6/11
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CaptchaServiceImpl implements CaptchaService {

    /**
     * 验证码配置
     */
    private final CaptchaProperties captchaProperties;

    /**
     * 验证验证码是否正确
     *
     * @param code       验证码
     * @param serverCode 验证码键
     * @throws CaptchaException 验证码异常
     */
    @Override
    public void validate(String code, String serverCode) throws CaptchaException {

        if (!captchaProperties.getEnabled()) {
            log.info("验证码校验已关闭");
            return;
        }
        if (!code.equals(serverCode)) {
            throw new CaptchaException(HttpStatus.UNAUTHORIZED.value(), "验证码错误");
        }
    }

    /**
     * 生成数字验证码
     *
     * @return {@link Result}<{@link Integer}>
     */
    @Override
    public CaptchaVo generateNumberCaptcha() {
        Integer code = RandomUtil.randomInt(1000, 9999);
        String codeKey = IdUtil.randomUUID();
        CaptchaVo captchaVO = CaptchaVo.builder()
                .code(String.valueOf(code))
                .codeKey(codeKey)
                .build();
        return captchaVO;
    }

    /**
     * 生成图像验证码
     *
     * @return {@link Result}
     */
    @Override
    public CaptchaVo generateImageCaptcha() {
        //定义图形验证码的长和宽

        // 获取验证码类型
        CaptchaEnum captchaEnum = captchaProperties.getCaptchaEnum();

        AbstractCaptcha captcha = getCaptcha(captchaEnum);


        //图形验证码写出，可以写出到文件，也可以写出到流
        String base64Prefix = "data:image/jpeg;base64,";
        String imageBase64 = base64Prefix.concat(captcha.getImageBase64());

        // code
        String code = captcha.getCode();
        String codeKey = IdUtil.randomUUID();

        return CaptchaVo.builder()
                .code(code)
                .codeKey(codeKey)
                .imgBase64(imageBase64)
                .build();
    }


    /**
     * 获取验证码对象
     *
     * @param captchaEnum 验证码枚举
     * @return {@link AbstractCaptcha}
     */
    private AbstractCaptcha getCaptcha(CaptchaEnum captchaEnum) {
        switch (captchaEnum) {
            case LINE_CAPTCHA:
                return CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(),
                        captchaProperties.getHeight(),
                        captchaProperties.getCodeCount(),
                        captchaProperties.getDisturbCount());
            case CIRCLE_CAPTCHA:
                return CaptchaUtil.createCircleCaptcha(captchaProperties.getWidth(),
                        captchaProperties.getHeight(),
                        captchaProperties.getCodeCount(),
                        captchaProperties.getDisturbCount());
            case SHEAR_CAPTCHA:
                return CaptchaUtil.createShearCaptcha(captchaProperties.getWidth(),
                        captchaProperties.getHeight(),
                        captchaProperties.getCodeCount(),
                        captchaProperties.getDisturbCount());
            default:
                return CaptchaUtil.createShearCaptcha(captchaProperties.getWidth(),
                        captchaProperties.getHeight());
        }
    }
}
